package com.project.frame.common.utils;

import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * desc
 *
 * @author lw007
 * @date 2021/12/24
 */
public class IdUtils {

    private AtomicInteger sequence = new AtomicInteger();
    private long prefix;
    private volatile long timestamp;
    private volatile int increment;

    private static IdUtils instance = new IdUtils();

    private IdUtils() {
        prefix = ((prefix & 0x0FFF) << 52) & 0xFFF0000000000000L;
    }

    public static long id() {
        long timestamp = (((System.currentTimeMillis() / 1000) & 0xFFFFFFFFL) << 20) & 0x0FFFFFFFF00000L;
        int increment = instance.sequence.getAndIncrement() & 0x0FFFFF;

        if (timestamp <= instance.timestamp) {
            while (timestamp < instance.timestamp) {
                timestamp += 0x100000L;
            }
            if (increment == instance.increment) {
                timestamp += 0x100000L;
            }
        } else {
            instance.increment = increment;
        }
        instance.timestamp = timestamp;

        return instance.prefix + timestamp + increment + 8;
    }

    public static String uuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    public static void main(String[] args) {

        for (int i = 0; i < 5; i++) {
            long id = IdUtils.id();
            System.out.println(id);
        }
    }

}
